<?php
/**
 * @author Eugenio Fage
 * http://eugeniofage.wordpress.com/
 * http://code.google.com/p/monky/
 * 
 */
class LinksController extends AppController {

	var $name = 'Links';

	var $components=array('RequestHandler');
	
	var $paginate=array(
		'Link'=>array(
			'fields'=>array('Link.id','Link.type','Link.status','Link.status_modified','Link.comment_status','Link.votes','Link.negatives', 'Link.anonymous', 'Link.karma', 'Link.modified','Link.url','Link.thumb', 'Link.title', 'Link.content','Link.comment_count'),
			'contain' => array(
				'Category'=>array('id','name'),'User'=>array('username','karma')
			),
			'order'=>array('Link.id'=>'DESC'),
			'limit' => 20,
		),'Comment'=>array(
			'fields'=>array('id','created','votes','karma','content'),				
			'contain'=>array(
				'User'=>array('username','karma')				
			),
			'order'=>array('Comment.id'=>'ASC'),
			'limit' => 20
		)
	);

	function beforeFilter(){
		parent::beforeFilter();
		$this->Auth->deny('add');
	}
	
	function index($cat_id=null) {
				
		//index are the published stories
		$this->paginate['Link']['order']=array('Link.status_modified'=>'DESC');	
		$this->_setIndex('published',$cat_id);	
	}
		
	function shakeit($cat_id=null) {
		$this->_setIndex('queued',$cat_id);
	}
	
	function popular($cat_id=null) {
		// @todo popular section
		
		$this->_setIndex('published',$cat_id);
	
		$min_date = date("Y-m-d H:i:00", $globals['now'] - 129600); // 36 hours 
		// The order is not exactly the votes
		// but a time-decreasing function applied to the number of votes
		$res = $db->get_results("select link_id, (link_votes-link_negatives*2)*(1-(unix_timestamp(now())-unix_timestamp(link_date))*0.8/129600) as value from links where link_status='published' $category_list and link_date > '$min_date' order by value desc limit 10");
	}

	function publish($id = null) {
		$this->disableCache();
		$link=$this->_getLink($id,array('Link.id','Link.status'));
			
		if(!($link['Link']['status']=='published')){
			//@todo acl responsability...
			$role=$this->Link->User->Group->field('name',array('id'=>$this->Auth->user('group_id')));
			
			if(!in_array($role, array('god','admin'))){
				$this->Session->setFlash(__('You are not an admin', true));
				$this->redirect(array('action' => 'view',$id));
			}
			
			$this->Link->publish($id);	
		}
		
		$this->Session->setFlash(__('The link has been published', true));
		$this->redirect(array('action' => 'view',$id));
		
	}
			
	function view($id = null) {
		$link=$this->_getLink($id,array('Link.*'),array('Category'=>array('id','name'), 'User'));
					
		$link['Category']['Parent']=$this->Link->Category->getparentnode($link['Category'],array('id','name'));
		if($link['isVotable']=$this->Link->isVotable($link,$this->Auth->user())){
			$link['voteValue']=$this->Link->Vote->getVoteValue($link['Link']['id'],$this->Auth->user('id'));
		}
				
		if(!isset($this->params['page'])){
			$page=intval(ceil($this->Link->Comment->find('count',array('conditions'=>array('Comment.link_id'=>$id),'recursive'=>-1)) / $this->paginate['Comment']['limit']));
			$this->params['page']=$page;
		}
		$comments=$this->paginate('Comment',array('Comment.link_id'=>$id));
		$comments=$this->Link->Comment->setCanVoteComments($comments,$this->Auth->user('id'));
		
		try{
			$this->Link->User->checkCanPostComment($this->Auth->user('id'),$id);
		}catch (CommentException $e){
			$this->set('error',$e->getMessage());
		}
		
		$this->set(compact('link', 'comments'));
	}
	
	function add() {
		try{
			$this->Link->User->checkCanPostLinks($this->Auth->user('id'));
			$paso=isset($this->data['Link']['paso']) ? $this->data['Link']['paso'] : 1;
			$this->set('paso',$paso);
			
			if (!empty($this->data) ) {
				if(isset($this->data['Link']['url'])){
					$this->Link->setPageobj($this->data['Link']['url']);
    				$this->data['Link']['url']=$this->Link->pageObj->url;
    				$this->data['Link']['checksum']=$this->Link->pageObj->checksum;

		   			$this->set(Page::getImagesFetchAndToFetch($this->Link->pageObj->images));
    			}
								
				if($paso==1){
					$this->_doAddStep1();
				}elseif ($paso==2){
					$this->_doAddStep2();
				}
				
				$this->set('pageObj',$this->Link->pageObj);
			}
						
			$this->set('warning',isset($this->Link->warning) ? $this->Link->warning : false);
		}catch (AddLinkException $linkException){
			$this->set('message',$linkException->getMessage());
			$this->render('/elements/error');
		}
	}
	
	function doVote(){
		if(empty($this->params['form'])|| !isset($this->params['form']['id'])) exit;
					
		$vote=array(
			'User'=>array(
				'id'=>(int)$this->Auth->user('id'),
				'vote'=>$this->params['form']['value']
			),'Link'=>array('id'=>$this->params['form']['id'])
		);
				
		try{
			$this->set('vote_result',am(array('msg'=>__('voted',true)),$this->Link->vote($vote)));
		}catch(ErrorVoteException $exception){
			$this->set('vote_result',array('error'=>$exception->getMessage(),'alert'=>$exception->getAlert()));
		}
		
		$this->layout = 'json';
		$this->render('json/vote');
	}
	

	function fetchImage(){
		// to prevent dos attacks 
		if(($this->Session->check('Fetchimage.'.$this->params['form']['key']) && ((time()-$this->Session->read('Fetchimage.'.$this->params['form']['key']))<20)) ||
			!isset($this->params['form']['key'])){
			exit;
		}
		
		App::import('vendor','robot');		
		// if the page itsnt in cache dont get images!
		if(!$p=Page::cacheRead($this->params['form']['url'])){
			exit;
		}
		
		extract(Page::getImagesFetchAndToFetch($p->images));
				
		if(count($fetchImg)>9){
			$this->Session->delete('Fetchimage');
			exit;
		}
		
		$this->set('result',false);
		foreach ($p->images as $img){
			if($this->params['form']['key']==md5($img)){
				$this->Session->write('Fetchimage.'.md5($img),time());
				$saved=$p->downloadImage($img);
				if(!$saved){
					$p=Page::cacheRead($this->params['form']['url']);
					$p->removeImage($img);
					$p->saveToCache();
				}
				$this->set('result',$saved);
				
				$this->Session->delete('Fetchimage.'.md5($img),time());
				break;
			}
						
		}
		
		$this->layout = 'json';
		$this->render('json/add');
				
	}

	function _getLink($id=null,$fields=array(),$contain=array()){
		$id=max($id,0);
		$conditions=array('Link.id'=>$id);
				
		$link=$this->Link->find('first',compact('fields','contain','conditions'));
		if(empty($link)){
			$this->Session->setFlash(__('Invalid link', true));
			$this->redirect(array('action' => 'index'));
		}
		
		return $link;
	}
	
	function _setIndex($link_status,$cat_id=null){
		if($cat_id){
			$cats=am(Set::extract($this->Link->Category->children($cat_id,true,array('id')),'{n}.Category.id'),$cat_id);
			$this->paginate['Link']['conditions']['Link.category_id']=$cats;
		}

		$this->paginate['Link']['conditions']['status']=$link_status;
				
		$this->set('links', $this->_paginateLink());	
	}
			
	function _paginateLink(){
		$paginate=parent::paginate($this->Link);
		$linksGetVoteValue=array();
		
		foreach ($paginate as $id=>$link){
			$paginate[$id]['Category']['Parent']=$this->Link->Category->getparentnode($link['Category']['id'],array('id','name'));			
			if($paginate[$id]['isVotable']=$this->Link->isVotable($link,$this->Auth->user())){
				$linksGetVoteValue[$id]=$link['Link']['id'];
	
			}
		}
		$voteValues=$this->Link->Vote->getLinksVoteValue($linksGetVoteValue,$this->Auth->user('id'));
		foreach ($voteValues as $pos=>$value) {
			$paginate[$pos]['voteValue']=$value;
		}
		
		return $paginate;
	}
	
	function _doAddStep1(){
		
		$this->Link->setValidateStep1();
		$this->Link->create($this->data);
				
		if($this->Link->validates()){
									
			if(!isset($this->Link->data['Link']['title'])||$this->Link->data['Link']['title']=='')$this->Link->data['Link']['title']=$this->Link->pageObj->title;
			if(!isset($this->Link->data['Link']['content'])||$this->Link->data['Link']['content']=='')$this->Link->data['Link']['content']=$this->Link->pageObj->description;
						
			$this->set('paso',2);
		}
			
		$this->data=array_merge($this->data,$this->Link->data);
		
				
	}
	
	function _doAddStep2(){	
		if ($this->Link->addLinkByUser($this->data,$this->Auth->user('id'))){	
			$this->Session->setFlash(__('The link has been saved', true));
			$this->redirect(array('action' => 'view',$this->Link->id));
		}
			
		$errors = $this->Link->invalidFields();
			
		if(isset($errors['url'])){
			if($id=$this->Link->getDuplicateLinkId($this->data)){
				$this->Link->id=$id;
				$this->Session->setFlash(__('The url has been send by another user', true));
				$this->redirect(array(
					'action' => 'view',
					'slug'=>Inflector::slug($this->Link->field('title')),
					$id
				));	
			}else{
				$this->Session->setFlash(__('Theres has been a fatal error while submitting your url; '. $errors['url'], true));
				$this->redirect(array('action' => 'add'));
			}
					
			$this->Session->setFlash(__('The link could not be saved. Correct the error fields and try again.', true));
		}
						
	}
}
?>
